home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
sampler0
/
dst100.asm
< prev
next >
Wrap
Assembly Source File
|
1988-11-08
|
38KB
|
944 lines
page 88,132
title DST.COM - DriveST.ASM
;-----------------------------------------------------------------------|
; PUBLIC DOMAIN MATERIAL by ScanSoft(tm) |
; 6402 Ingram Rd., San Antonio, TX 78238 |
;-----------------------------------------------------------------------|
; program: DriveST.ASM (DST.COM) |
; |
; version: 1 |
; |
; by: Cornel Huth |
; |
; date: Nov 05 88 |
; |
; function: display drive status on |
; line 26 of CGA, EGA/VGA and line 1 of MDA |
; |
; caller: user timer interrupt 1Ch (18.2 times/sec) |
; |
; use: C>DST * install TSR |
; DST /- * remove from memory (if possible) |
; DST /d * make dormant (norm screen, unchain if poss) |
; DST /r * restore status line; awaken if dormant |
; DST /a * autopark HD C:(after 30 seconds of inactivity)|
; |
; |
; notes: CPU overhead: 4.77 MHz 8088 3.2 |
; 8.00 MHz 8088 1.8 |
; 6.00 MHz 80286 0.5 |
; when DORMANT none |
; |
; if using MDA, press <Alt> to deactivate status printing|
; on line 1 or use Scroll Lock (on) for continuous |
; non-display (allows viewing of line 1) |
; |
;------------------------------------------------------------------------
subttl BIOS segment description
;DEBUGCGA equ 1
BIOS_SEG SEGMENT AT 0040h
ORG 17h
KBDflags1 db ? ;keyboard toggle flags
ORG 41h
status db ? ;controller status (not all BIOS's update here)
drive db ? ;low nybble = 0 then A:
;low nybble = 1 then B:
;low nybble >=8 then HD
headHD db ? ;current HD head (0 to heads on device - 1)
cylHI label byte ;bits 6 & 7 represent HI cylinder * 256
secHD label byte ;bits 0 - 5 represent sector of HD only
db ?
cylLO db ? ;LO cylinder (0 - 255 + (cylHI * 256)if HD)
headFD db ? ;current floppy head (0 or 1)
secFD db ? ;sector of floppy only
ORG 49h
modeCRT db ? ;current mode of video system
ORG 62h
pageCRT db ? ;active page of display
ORG 63h
addrCRTC dw ? ;CRTC address register I/O port
ORG 87h
EGAinfo db ? ;EGA info byte (0 only if 64K EGA or no EGA)
EGAinfo2 db ? ;checked if EGAinfo = 0 (this is 0 if no EGA)
BIOS_SEG ENDS
subttl Resident code and data
DriveST_SEG SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:DriveST_SEG,ds:DriveST_SEG,es:NOTHING
org 100h
;need 16 bytes of constant data after go: for DUP install check
go: jmp start
checkdata db 'DST v1.0 (PD)'
ERRORMSG db 'ERROR '
OKMSG db 'OK '
PARKMSG db 'PARKED'
EGA_data dw 5 ;registers to change for EGA/VGA (reg, data)
EGA_26_data db 06h,07Ah,12h,06Bh,15h,06Ch,10h,06Ch,16h,000h
EGA_25_data db 06h,06Ch,12h,05Dh,15h,05Eh,10h,05eh,16h,00Ah
EGA_VGA db 0
M6845_data dw 1 ;registers to change
M6845_26_data db 06h,26
M6845_25_data db 06h,25
CGA db 0 ;CGA uses the M6845 CRTC (MCGA should be compatible)
M6845_data7 dw 0 ;registers to change
M6845_26_data7 db 0,0
M6845_25_data7 db 0,0
MDA db 1 ;MDA is 'worst' case
VALIDMODE db 0 ;= 1 if operating in a compatible video mode
WasError db 0 ;= 32 if drive error (bg from blk on grn to blk on red)
Busy1C dw 0 ;= 1 if already in our New_1C routine
OLD_1C dd ? ;interrupt vector for old user timer interrupt
CRTCaddr dw 03D4h ;CRTC reg addr
Video_Seg dw 0B800h ;segment of video diplay
Video_Page db 0 ;active video page
Video_PageOff dw 0 ;offset into video segment of page
CmdLineParm db 0 ;command line parameter (preceded by a /)
StatLnOff dw 0 ;offset into video buffer of Status line (4000/26,0/1)
StatLnCol dw 0 ;column of first characater of StatLn
StatLnAttr db 0 ;character attribute of StatLn
StatLn db 'drv: cyl: sec: head: stat: '
StatLnend label word
TickTrip equ 546 ;ticks approx = 30 seconds (546/18.2=30)
ticks dw 0 ;tick cnt since HD active (if DoAuto and not parked)
DoAuto db 0 ;= 1 then park if ticks > TickTrip
Parked db 0 ;= 1 then HD is already parked
JustPark db 0 ;= 1 if we just parked, = 0 if not
LastCylSec db 0 ;last cylinder/sector in BIOS form
LastCyl db 0 ;last cylinder (low)
LastSec db 0 ;last sector
LastHead db 0 ;last head
New_1C PROC FAR
ASSUME ds:NOTHING, es:NOTHING
sti
push ax
push bx
push cx
push dx
push bp
push di
push si
push es
push ds
pushf ;preserve callings flags in case needed
cld ;a must
mov ax,cs
mov ds,ax ;point ds to data
ASSUME ds:DriveST_SEG
inc ticks ;let's time the need for a park
cmp Busy1C,0 ;are we BUSY?
jne New_1Cxit
mov Busy1C,1 ;no, make us BUSY
mov ax,0040h
mov es,ax
ASSUME es:NOTHING
cmp DoAuto,1 ;autopark on?
je New_1C1 ;yes
mov ticks,0 ;no, zero ticks for a fresh start on /a
New_1C1: call Xlate_BIOS ;es->BIOS
cmp ticks,TickTrip ;need to park?
jb New_1C2 ;no
cmp Parked,1 ;already parked?
je New_1C2 ;yes
call ParkC
New_1C2: call Get_Video_Info ;es->BIOS (after)
cmp VALIDMODE,1 ;are we valid?
jne New_1Cxit ;no
lea dx,StatLn
mov cx,offset StatLnend - offset StatLn
mov ah,StatLnAttr
cmp MDA,1
jne New_1C3
test es:KBDflags1,18h;is <Alt> down or <Scroll Lock> on?
jnz New_1Cxit ;yes, no display of MDA status
cmp WasError,0
je New_1C4
mov ah,07 ;normal video on error for MDA
jne New_1C4
New_1C3: add ah,WasError ;WasError = (2*16) if disk error
New_1C4: mov bx,StatLnCol ;start column of StatLn
call Write_StatLn
New_1Cxit: popf
pop ds
pop es
ASSUME ds:NOTHING, es:NOTHING
pop si
pop di
pop bp
pop dx
pop cx
pop bx
pop ax
cli ;turn off (OLD_1C or IRET turns it on)
mov cs:Busy1C,0 ;make us READY
jmp cs:OLD_1C
New_1C ENDP
;
; get video system information
;
Get_Video_Info PROC NEAR
ASSUME ds:DriveST_SEG, ds:NOTHING
mov ax,0040h
mov es,ax
ASSUME es:NOTHING
mov MDA,1 ;assume 'worst case'
mov VALIDMODE,0 ;ditto
mov CGA,0 ;these may change from zero
mov EGA_VGA,0 ;so zero then here
cmp es:modeCRT,2 ;valid modes are 2, 3, 7
jb GVIjmp ;below 2 invalid
cmp es:modeCRT,7 ;7 ok
je GVI0
cmp es:modeCRT,4
jb GVI0 ;2 or 3 ok
GVIjmp: jmp GVIxit
; get the CRTC port address
GVI0: cmp es:addrCRTC,03D4h ;color?
jne GVI1
mov MDA,0 ;yes, we know it's not mono
mov Video_Seg,0B800h ;video base segment of color
mov CRTCaddr,03D4h ;its controller
mov StatLnOff,4000 ;StatLn offset (line 26)
mov StatLnCol,0 ;StatLn column (col 1)
mov StatLnAttr,0+(2*16) ;black on green
je GVI2
GVI1: mov Video_Seg,0B000h ;mono's video base segment
mov CRTCaddr,03B4h ;its controller
mov StatLnOff,0 ;StatLn offset (line 1)
mov StatLnCol,0 ;StatLn column (col 1)
mov StatLnAttr,70h ;reverse video
jmp short GVI4
GVI2: cmp es:EGAinfo,0 ;64K EGA or no EGA?
jne GVI2a ;no, an EGA with >64K
cmp es:EGAinfo2,0 ;no EGA at all?
je GVI3 ;should be a CGA
GVI2a: mov EGA_VGA,1
jne GVI4
GVI3: mov CGA,1 ;it's CGA (MCGA may work, not tested)
GVI4: mov VALIDMODE,1
;calculate offset into video buffer of the current page
mov al,es:pageCRT
cmp al,Video_Page ;still using same page?
je GVIxit
mov Video_Page,al ;no, inform DST of new page
xor bh,bh
mov bl,Video_Page
mov ax,1000h ;video page size (based on 80 X 25)
mul bx ;times page (0-7)
mov Video_PageOff,ax
GVIxit: ret
Get_Video_Info ENDP
;
; program CRTC to display 26 lines
;
Set_Line26 PROC NEAR
ASSUME ds:DriveST_SEG
cmp MDA,1 ;skip if MDA
jne SL261
ret
SL261: mov dx,CRTCaddr ;CRTC port address
cmp EGA_VGA,1
jne SL26_M6845
mov cx,EGA_data ;set up EGA (byte 1 = # data)
mov si,offset EGA_26_data
je SL26_LR
SL26_M6845: mov cx,M6845_data ;set up M6845 (CGA/MCGA)
mov si,offset M6845_26_data
SL26_LR: cli ;interrupts off
SL26_LR1: lodsb
out dx,al ;CRTC register
lodsb
inc dx
out dx,al ;data
dec dx
loop SL26_LR1
sti ;interrupts on
ret
Set_Line26 ENDP
;
; program CRTC to display 25 lines
;
Set_Line25 PROC NEAR
ASSUME ds:DriveST_SEG
cmp MDA,1 ;skip if MDA
jne SL251
ret
SL251: mov dx,CRTCaddr ;as Set_Line26
cmp EGA_VGA,1
jne SL25_M6845
mov cx,EGA_data
mov si,offset EGA_25_data
jmp short SL25_LR
SL25_M6845: mov cx,M6845_data
mov si,offset M6845_25_data
SL25_LR: cli
SL25_LR1: lodsb
out dx,al
lodsb
inc dx
out dx,al
dec dx
loop SL25_LR1
sti
ret
Set_Line25 ENDP
;
; write the status
;
Write_StatLn PROC NEAR
ASSUME ds:DriveST_SEG
;ENTER with...
;ds:dx -> DST write buffer
;cx: length of write buffer
;bx: start in this column of line
;ah: attribute of characters in line
mov bp,Video_Seg
mov es,bp
ASSUME es:NOTHING
shl bx,1 ;multiply column by 2 (2 bytes/column)
add bx,Video_PageOff ;add adjustment for video page
add bx,StatLnOff ;add offset into video buff of StatLn
mov di,bx ;es:di -> destination
mov si,dx ;ds:si -> source
WR26: lodsb ;get a character from the write buffer
stosw ;store it and the attribute
loop WR26 ;print cx char/attr pairs
ret
Write_StatLn ENDP
Xlate_BIOS PROC NEAR
ASSUME ds:DriveST_SEG, es:NOTHING
;es->BIOS SEG
mov al,es:drive ;controller status/drive
mov di,offset StatLn+38
mov cx,6 ;length of messages
test al,11000000b ;test for normal termination
jz XLB1
lea dx,ERRORMSG ;error of some sort
mov si,dx
mov WasError,(2*16) ;attr=red bg on error (attr+WasError)
jmp short XLB2
XLB1: lea dx,OKMSG ;normal termination
and al,0Fh ;isolate low nybble
cmp al,8
jb XLB1a ;a floppy
cmp Parked,1 ;are we parked?
jne XLB1a
lea dx,PARKMSG ;yes
XLB1a: mov si,dx
mov WasError,0 ;normal attr
XLB2: push es
push cs
pop es ;es:di -> write buffer
ASSUME es:NOTHING
rep movsb ;write the message to the write buffer
pop es ;get back es->BIOS
ASSUME es:NOTHING
cmp al,8 ;again, <8 = floppy
jnb XL_HD
jmp XL_floppy
XL_HD: mov al,"C" ;I am assuming one HD and that it is C:
mov [StatLn+4],al
mov al,es:headHD ;head
cmp LastHead,al ;* check last head
je XLB3
mov ticks,0 ;different so zero ticks (safe)
mov LastHead,al ;update new last head
cmp JustPark,1 ;just did a park?
je XLB3 ;yes
mov Parked,0 ;no, then we cannot be parked
XLB3: add al,'0'
mov [StatLn+30],al
mov ah,es:cylHI ;let's get the cyl hi
mov LastCylSec,ah ;used by ParkErrorError only
rol ah,1 ;move cyl hi bits @ 6&7 to bits 0&1
rol ah,1
and ah,00000011b ;isolate cyl hi
mov al,es:cylLO ;cylinder low (ax = 10 bit cylinder)
cmp LastCyl,al ;* check last cylinder low (safe enough)
je XLB4 ;* note we're not checking cyl hi
mov ticks,0 ;different so zero ticks
mov LastCyl,al ;update new last cylinder
cmp JustPark,1 ;just did a park?
je XLB4 ;yes
mov Parked,0 ;no, then we cannot be parked
XLB4: mov di,offset StatLn+11
mov cx,4 ;number of digits
call AX2DEC
mov al,es:cylHI ;isolate sector
and al,00111111b ;bits 0 - 5
cmp LastSec,al ;* check last sector
je XLB5
mov ticks,0 ;different so zero ticks
mov LastSec,al ;update new last sector
cmp JustPark,1 ;just did a park?
je XLB5 ;yes
mov Parked,0 ;no, then we cannot be parked
XLB5: xor ah,ah
mov di,offset StatLn+21-2 ;-2 since cx = 4-2
mov cx,2
call AX2DEC
mov JustPark,0 ;no longer just did a park now
ret
XL_floppy: and al,00000011b ;drive 0-3
add al,'A'
mov [StatLn+4],al
mov al,es:headFD
and al,00000001 ;head 0-1
add al,'0'
mov [StatLn+30],al
xor ah,ah
mov al,es:cylLO ;track
mov di,offset StatLn+11
mov cx,4 ;number of digits (HD cover up)
call AX2DEC
xor ah,ah
mov al,es:secFD
mov di,offset StatLn+21-2 ;-2 since cx = 4-2
mov cx,2
call AX2DEC
ret
Xlate_BIOS ENDP
; ENTER with:
; ax = int value 0-9999
; cx = number of digits to interpret
; di -> buffer
; EXIT with:
; ASCII value of ax in di->buffer
AX2DEC PROC NEAR
ASSUME ds:DriveST_SEG
;divide by 10 - get remainder
mov bx,10 ; divisor
xor dx,dx ; using AX as dividend
div bx ; remainder in dx
add dl,"0" ; to ASCII
mov byte ptr [di+3],dl ; store it
cmp cx,1
je AX2DECxit
;tens
xor dx,dx
div bx
add dl,"0"
mov byte ptr [di+2],dl
cmp cx,2
je AX2DECxit
;hundreds
xor dx,dx
div bx
add dl,"0"
mov byte ptr [di+1],dl
cmp cx,3
je AX2DECxit
;thousands
xor dx,dx
div bx
add dl,"0"
mov byte ptr [di],dl
AX2DECxit: ret
AX2DEC ENDP
ParkC PROC NEAR
ASSUME ds:DriveST_SEG
mov dl,80h
mov ah,08h
int 13h ;get HD info (when dl >= 80h)
;ch = last cyl(lo) position
;cl = cyl(hi)(bits 6-7) & sec/cyl (0-5)
;dh = sides (0 based)
;dl = number of HD's
cmp dl,0 ;any HD's?
je ParkCxit
cmp dl,80h ;HD BIOS not there?
je ParkCxit
mov dl,80h ;select first HD
push cx ;save cyl/sec info
rol cl,1 ;move bits 6 & 7 to bit positions 0 & 1
rol cl,1 ; moving sec/cyl to bits 2-7
xchg cl,ch ;put hi cyl&sec in ch and lo cyl in cl
and cx,03FFh ;make 10-bit last cyl & zero sector
inc cx ;let's make it last cyl+1
xchg cl,ch ;put hi cyl in cl and lo cyl in ch
ror cl,1 ;move bits 0 & 1 back to bit pos 6 & 7
ror cl,1 ; moving sec/cyl back to bits 0 - 5
or cl,01h ;sector to 1 (physical HD sector 0)
mov dh,0 ;head to 0
mov ah,0Ch ;seek to cylinder (AT BIOS documented)
int 13h ; should work for >10MEG HD controller
jc ParkError ;an error
mov Parked,1 ;we're parked
mov JustPark,1 ;just now did it
mov ticks,0 ;zero (for completeness)
clc
pop cx ;remove saved cyl/sec info
ParkCxit: ret
ParkError: mov dl,80h ;select first HD
pop cx ;get saved cyl/sec info
rol cl,1
rol cl,1
xchg cl,ch
and cx,03FFh ;no inc this time
xchg cl,ch
ror cl,1
ror cl,1
or cl,01h
mov dh,0
mov ah,0Ch ;seek to last cyl (not last cyl+1)
int 13h
jc ParkErrorError ;another error
mov Parked,1
mov JustPark,1
mov ticks,0
clc
ParkErrorxit: ret
ParkErrorError: mov dl,80h
mov ch,LastCyl ;get last cylinder low
mov cl,LastCylSec ;and last cylinder hi and sector
mov dh,0
mov ah,0Ch ;seek to previous cylinder
int 13h
mov Parked,0
mov JustPark,0
mov ticks,0
stc
ret
ParkC ENDP
subttl Installation code
;===============================================
;let's install it - code after start is not kept
;===============================================
ASSUME cs:DriveST_SEG,ds:DriveST_SEG
start: cld
lea dx, Copyright ;it is PD material
mov ah,9
int 21h ;DOS print string
call GetParm
;---------------------
not byte ptr go ;modify to avoid self-match
xor bx,bx ;start search at segment zero (really 1)
mov ax,cs ;compare to current code segment
start1: inc bx ;look at next segment
cmp ax,bx ;until reaching this code seg
mov es,bx
je start3
mov si,offset go ;set up to compare strings
mov di,si
mov cx,16 ;16 bytes must match
rep cmpsb ;compare ds:si to es:di
or cx,cx ;did the strings match?
jnz start1 ;if no match, try next segment
;else fall through (already installed)
; with es -> matching code segment
cmp CmdLineParm,'-' ;unchain
jne startR
jmp Unchain
startR: and CmdLineParm,255-32 ;make it uppercase
cmp CmdLineParm,'R' ;restore 26 lines; awaken if dormant
jne startD
jmp RedoStatLn
startD: cmp CmdLineParm,'D' ;sleep
jne startA
jmp Sleep
startA: cmp CmdLineParm,'A' ;autopark
jne start?
jmp AutoPark
start?: lea dx,Use
cmp CmdLineParm,0
jne start2 ;invalid parm
lea dx,DupMsg ;no parms?,(/) already installed msg
start2: mov ah,9
int 21h
mov al,1
jmp Exit4c
start3: lea dx,Use ;we're not installed
mov ah,9
int 21h
jmp notinstalled
;---------------------
;es->match segment
AutoPark: mov es:ticks,0 ;set TSR data
mov es:Parked,0
mov es:JustPark,0
mov es:DoAuto,1
lea dx,AutoMsg
mov ah,9
int 21h
mov al,0
jmp Exit4c
;---------------------
Sleep: push es ;save TSR's segment
mov ax,351Ch ;get current timer interrupt (1Ch)
int 21h
pop ax
mov dx,es
cmp ax,dx ;compare matched seg with 1Ch seg
jne Sleep2 ;cannot sleep since seg has changed
push ax
pop es ;get back es
mov dx,es:word ptr Old_1C
mov ax,es:word ptr Old_1C+2
mov ds,ax
mov ax,251Ch
int 21h
mov ax,cs ;restore ds
mov ds,ax
call Get_Video_Info
cmp VALIDMODE,1
mov ax,0
push ax ;save errorlevel
jne Sleep1
call Set_Line25 ;only if in a valid mode
Sleep1: lea dx,SleepMsg
jmp short Sleep3
Sleep2: lea dx,NoSleepMsg
mov ax,1
push ax ;save errorlevel
Sleep3: mov ah,9
int 21h
pop ax
jmp Exit4c
;---------------------
RedoStatLn: push es ;save es
call Get_Video_Info
pop es
cmp VALIDMODE,1
je RedoStatLn1
lea dx,NoRestoreMsg
mov ah,9
int 21h
mov al,1
jmp Exit4c
RedoStatLn1: call Set_Line26
lea dx,Redo26Msg
mov ah,9
int 21h
push es ;save es
mov ax,351Ch ;get current timer interrupt (1Ch)
int 21h ; since it may have changed
mov cx,es ;save int 21h's es into cx
pop es ;get back es
mov dx,es
cmp cx,dx ;if interrupt 1Ch has changed
jne RedoStatLn2 ; then need to awaken
je RedoStatLn3
RedoStatLn2: mov es:word ptr [Old_1C],bx ;save current offset in TSR
mov es:word ptr [Old_1C+2],cx ;save current segment
mov dx,offset New_1C
push es
pop ds ;matching code seg
ASSUME ds:NOTHING
mov ax,251Ch
int 21h ;set interrupt (1Ch) (time to awaken)
push cs
pop ds ;get back ds
ASSUME ds:DriveST_SEG
RedoStatLn3: mov ah,0
jmp Exit4c
;---------------------
;es -> matching segment
Unchain: push es ;save TSR's segment
mov ax,351Ch ;get current timer interrupt (1Ch)
int 21h
pop ax
mov dx,es
cmp ax,dx ;compare matched seg with 1Ch seg
jne Unchain4 ;cannot unchain since seg has changed
mov es,ax ;get back es
mov dx,es:word ptr Old_1C
mov ax,es:word ptr Old_1C+2
mov ds,ax
mov ax,251Ch ;set timer interrupt to interrupt valid
int 21h ; when installed
mov ax,cs ;restore ds
mov ds,ax
not es:byte ptr go ;precludes matching on next install
mov cx,es ;save es -> PSP/COM BLOCK (not in EXE's)
mov bx,es:[002Ch] ;segment address of environment block
mov es,bx
mov ah,49h
int 21h ;release the environment block
jc Unchain1 ;an error
mov es,cx
mov ah,49h ;release the TSR block
int 21h
jnc Unchain2
Unchain1: lea dx,DeAllocMsg ;memory dealloc error
mov ah,9
int 21h
mov al,1
jmp short Exit4c
Unchain2: call Get_Video_Info
cmp VALIDMODE,1
jne Unchain3
call Set_Line25 ;only if in a valid mode
Unchain3: lea dx,UniMsg
mov ah,9
int 21h
mov al,00h
;---------------------
Exit4c: mov ah,4Ch
int 21h
;---------------------
Unchain4: lea dx,NoUnchain
mov ah,9
int 21h
mov al,1
jmp short Exit4c
;---------------------
notinstalled: cmp CmdLineParm,0 ;not yet installed, should be no parms
je notinstalled1
lea dx,NotInstalledMsg
mov ah,9
int 21h
mov al,1
jmp short Exit4c
;---------------------
notinstalled1: call Get_Video_Info
cmp VALIDMODE,1 ;are we in a valid mode?
je notinstalled2
lea dx,NoInstallMsg
mov ah,9
int 21h
mov al,1
jmp short Exit4c
;---------------------
notinstalled2: mov ax,351Ch ;get timer interrupt (1Ch)
int 21h
mov word ptr [Old_1C],bx ;save offset
mov word ptr [Old_1C+2],es ;save segment
mov dx,offset New_1C
mov ax,251Ch
int 21h ;set new interrupt (1Ch)
call Set_Line26
call EntryAt
lea dx,EntryAtMsg ;1Ch entry address
mov ah,9
int 21h
mov dx,offset start
mov cl,4
shr dx,cl
inc dl
inc dl
mov ax,3100h
int 21h ;Terminate - stay resident (keep up to start)
subttl Installation called routines
;---------------------
GetParm: mov si,81h
mov CmdLineParm,0
GetParm1: mov bl,[si]
cmp bl,0dh
je GetParm_Exit
inc si
cmp bl,'/'
jne GetParm1
mov bl,[si]
mov CmdLineParm,bl
GetParm_Exit: ret
;
; byte in al to two-byte ASCII hex in ax (A5 to 'A5')
;
ConvByte2ASCII PROC NEAR
ASSUME ds:DriveST_SEG
push cx
mov cl,4 ;mult x 16
xor ah,ah ;just the low-order byte
push ax ;save data passed in AX
and al,0F0h ;hi-order nybble
shr al,cl ;div hi-nybble by 16
ConvB: cmp al,9 ;hex letter?
jna ConvBdec
add al,55 ;10+55=65(A)
jmp short ConvB1
ConvBdec: add al,'0' ;adjust ASCII to decimal 9+30h(0)=39h(9)
ConvB1: cmp cl,0 ;done both ASCII bytes?
je ConvB2 ;*** exit 2x loop here
xchg al,ch ;save it
pop ax ;get it again
and al,0Fh ;low-order nybble
mov cl,0 ;make it last time around
jmp short ConvB ;do low-order nybble
ConvB2: xchg ch,ah ;get hi-order
xchg al,ah ;put in correct order
clc ;and we're done
pop cx
ret
ConvByte2ASCII endp
;
; get 1Ch entry address
;
EntryAt PROC NEAR
ASSUME ds:DriveST_SEG
mov bx,offset EntryAtMsg+7
mov ax,cs
xchg ah,al
call ConvByte2ASCII ;seg high byte
mov word ptr [bx],ax
mov ax,cs
call ConvByte2ASCII ;seg low byte
mov word ptr [bx+2],ax
mov ax,offset New_1C
xchg ah,al
call ConvByte2ASCII ;off high byte
mov word ptr [bx+5],ax
mov ax,offset New_1C
call ConvByte2ASCII ;off low byte
mov word ptr [bx+7],ax
ret
EntryAt ENDP
subttl Installation messages
DeAllocMsg db '*** Error in releasing memory - suggest a REBOOT ASAP!'
db 13,10,7,'$'
NoSleepMsg db '*** Cannot become dormant - interrupt 1Ch has changed.'
db 13,10,7,'$'
NoInstallMsg db '*** Cannot install - must be in BIOS video modes 2, 3, or 7.'
db 13,10,7,'$'
NoRestoreMsg db '*** Cannot restore - must be in BIOS video modes 2, 3, or 7.'
db 13,10,7,'$'
NoUnchain db '*** Cannot remove from memory - interrupt 1Ch has changed.'
db 13,10,7,'$'
NotInstalledMsg db '*** Parameter ignored - DST is NOT installed.'
db 13,10,7,'$'
DupMsg db '*** Already installed - use DST /r to restore.'
db 13,10,7,'$'
Copyright db 'DST 1.0 - Public Domain material brought to you by Cornel Huth. '
db 13,10,'$'
Use db 13,10
db 'Use: DST * install TSR ',13,10
db ' DST /- * remove from memory ',13,10
db ' DST /d * make dormant ',13,10
db ' DST /r * restore status line; awaken if dormant ',13,10
db ' DST /a * activate autopark of hard disk C: ',13,10
db 13,10,'$'
EntryAtMsg db '[0x1C] 0000:0000 '
db 13,10,'$'
UniMsg db 'Released from memory. Use DST to install again.'
db 13,10,'$'
SleepMsg db 'Dormant. Use DST /r to restore.'
db 13,10,'$'
Redo26Msg db 'Restored.'
db 13,10,'$'
AutoMsg db 'Autopark of hard disk C: activated.'
db 13,10,'$'
DriveST_SEG ENDS
END go